package com.egg.demo.controller.web;


import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.egg.basic.model.response.DateTest;
import com.egg.common.core.model.controller.WebController;
import com.egg.common.core.model.response.ResponseData;
import com.egg.common.util.SecureUtil;
import com.egg.demo.entity.test.Test;
import com.egg.demo.secure.annotation.Decrypt;
import com.egg.demo.secure.annotation.Encrypt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;

@Slf4j
@Api(tags = WebController.API_PREFIX + "加解密")
@RestController
@RequestMapping("/secure")
public class WebSecureController extends WebController {


    @ApiOperation(value = "流程示例")
    @GetMapping
    public ResponseData<DateTest> get() {
        System.out.println("第一阶段开始...");
        // 第一步, 生成公私钥
        HashMap<String, String> pairHashMap = SecureUtil.rsaGenerateKeyPair();
        System.out.println("后端生成临时公私秘钥对: " + pairHashMap.toString());
        // 第二步, 将 pairHashMap 放入缓存
        // 第三步, 返回公钥给前端
        String publicKey = SecureUtil.rsaPublicKey(pairHashMap);
        System.out.println("前端获取临时公钥: " + publicKey);
        // 第四步, 前端生成对称秘钥
        String aes = RandomUtil.randomString(32);
        System.out.println("前端生成对称秘钥原文: " + aes);
        // 第五步, 前端用公钥加密秘钥
        String aseEncrypt = SecureUtil.rsaEncryptByPublic(publicKey, aes);
        System.out.println("前端用公钥加密对称秘钥密文: " + aseEncrypt);
        // 第六步, 后端获取私钥
        String privateKey = SecureUtil.rsaPrivateKey(pairHashMap);
        System.out.println("后端用公钥获取私钥: " + privateKey);
        // 第七步, 后端用私钥解密对称加密密文获取对称加密秘钥
        String rsaDecrypt = SecureUtil.rsaDecryptByPrivate(privateKey, aseEncrypt);
        System.out.println("后端用私钥解密对称秘钥密文: " + rsaDecrypt);
        // 第八步, 后端保存对称秘钥 rsaDecrypt
        System.out.println("后端保存对称秘钥明文...");
        System.out.println("第一阶段结束...");

        System.out.println("第二阶段开始...");
        // 第九步, 前端加密对称秘钥加密请求数据
        JSONObject sourceRequest = new JSONObject();
        sourceRequest.put("id", 10086);
        sourceRequest.put("name", "中国移动我不动");
        String sourceRequestStr = sourceRequest.toJSONString();
        System.out.println("前端生成请求明文: " + sourceRequestStr);
        String aesEncryptRequest = SecureUtil.aesEncrypt(aes, sourceRequestStr);
        System.out.println("前端发送请求密文: " + aesEncryptRequest);

        // 第十步, 后端解密对称密文
        String aesDecryptRequest = SecureUtil.aesDecrypt(aes, aesEncryptRequest);
        System.out.println("后端获取请求明文: " + aesDecryptRequest);

        // 第十一步, 后端返回加密密文
        JSONObject sourceResponse = new JSONObject();
        sourceResponse.put("id", 10010);
        sourceResponse.put("name", "中国联通我不通");
        String sourceResponseStr = sourceResponse.toJSONString();
        System.out.println("后端生成响应明文: " + sourceResponseStr);
        String aesEncryptResponse = SecureUtil.aesEncrypt(aes, sourceResponseStr);
        System.out.println("后端生成响应密文: " + aesEncryptResponse);

        // 第十二步, 前端解析后端返回的密文
        String aesDecryptResponse = SecureUtil.aesDecrypt(aes, aesEncryptResponse);
        System.out.println("前端解密响应密文: " + aesDecryptResponse);
        System.out.println("第二阶段结束...");
        return ResponseData.success();
    }


    @ApiOperation(value = "对称加密")
    @GetMapping("/aes/encrypt/let")
    public ResponseData<String> secureAesEncrypt(
            @ApiParam(value = "需要加密的明文", required = true) @RequestParam(value = "content") String content
    ) {
        String aesDecryptContent = SecureUtil.aesEncrypt("对称秘钥凑满32位:12345678", content);
        return ResponseData.success(aesDecryptContent);
    }

    @ApiOperation(value = "对称解密")
    @GetMapping("/aes/decrypt/let")
    public ResponseData<String> secureAesDecrypt(
            @ApiParam(value = "需要解密的密文", required = true) @RequestParam(value = "content") String content
    ) {
        String aesDecryptContent = SecureUtil.aesDecrypt("对称秘钥凑满32位:12345678", content);
        return ResponseData.success(aesDecryptContent);
    }

    @Encrypt
    @Decrypt
    @ApiOperation(value = "请求数据解密/返回数据加密接口")
    @PostMapping("/encrypt-decrypt/text")
    public ResponseData<String> encryptDecryptText(@RequestBody Test test) {
        String s = JSON.toJSONString(test);
        log.info("解密/加密接口收到数据 {}", s);
        return ResponseData.success(s);
    }

    @Encrypt
    @ApiOperation(value = "返回数据加密接口")
    @PostMapping("/encrypt/text")
    public ResponseData<String> encryptText(@RequestBody Test test) {
        String s = JSON.toJSONString(test);
        log.info("解密接口收到数据 {}", s);
        return ResponseData.success(s);
    }

    @Decrypt
    @ApiOperation(value = "请求数据解密接口")
    @PostMapping("/decrypt/text")
    public ResponseData<String> decryptText(@RequestBody Test test) {
        String s = JSON.toJSONString(test);
        log.info("解密接口收到数据 {}", s);
        return ResponseData.success(s);
    }


    @ApiOperation(value = "明文接口")
    @PostMapping("/text")
    public ResponseData<String> text(@RequestBody Test test) {
        String s = JSON.toJSONString(test);
        log.info("明文接口收到数据 {}", s);
        return ResponseData.success(s);
    }


}

